package biz

import (
	"context"
	"strconv"

	"github.com/go-kratos/kratos/contrib/registry/consul/v2"
	"github.com/go-kratos/kratos/v2/middleware/tracing"
	"github.com/go-kratos/kratos/v2/transport/grpc"
	"github.com/hashicorp/consul/api"
	"gorm.io/gorm"

	"valuation-srv/api/mapsrv"
)

// PriceRuleInterface 定义操作 priceRule 的接口
type PriceRuleInterface interface {
	// GetRule 获取规则
	GetRule(cityId uint, curr int) (*PriceRule, error)
}

type ValuationBiz struct {
	pri PriceRuleInterface
}

func NewValuationBiz(pri PriceRuleInterface) *ValuationBiz {
	return &ValuationBiz{pri: pri}
}

func (b *ValuationBiz) GetDrivingInfo(ctx context.Context, origin, destination string) (distance, duration string, err error) {
	consulConfig := api.DefaultConfig()
	consulConfig.Address = "localhost:8500"
	consulClient, err := api.NewClient(consulConfig)
	if err != nil {
		return
	}
	reg := consul.New(consulClient)
	conn, err := grpc.DialInsecure(
		ctx,
		grpc.WithEndpoint(MapServiceName),
		grpc.WithDiscovery(reg),
		grpc.WithMiddleware(tracing.Client()),
	)
	if err != nil {
		return
	}
	defer func() {
		_ = conn.Close()
	}()

	client := mapsrv.NewMapServiceClient(conn)
	reply, err := client.GetDrivingInfo(context.Background(), &mapsrv.GetDrivingInfoReq{
		Origin:      origin,
		Destination: destination,
	})
	if err != nil {
		return
	}
	distance, duration = reply.Distance, reply.Duration
	return
}

// GetPrice 获取价格 curr 运营时间
func (b *ValuationBiz) GetPrice(ctx context.Context, distance, duration string, cityId uint, curr int) (int64, error) {
	// 一，获取规则
	rule, err := b.pri.GetRule(cityId, curr)
	if err != nil {
		return 0, err
	}
	// 二，将距离和时长，转换为int64
	distanceInt64, err := strconv.ParseInt(distance, 10, 64)
	if err != nil {
		return 0, err
	}
	durationInt64, err := strconv.ParseInt(duration, 10, 64)
	if err != nil {
		return 0, err
	}

	// 三，基于rule计算
	distanceInt64 /= 1000 // 转成 km
	durationInt64 /= 60 // 转成 min
	var startDistance int64 = 5
	total := rule.StartFee + rule.DistanceFee*(distanceInt64-startDistance) + rule.DurationFee*durationInt64
	return total, nil
}

type PriceRule struct {
	gorm.Model
	PriceRuleWork
}

type PriceRuleWork struct {
	CityID      uint
	StartFee    int64
	DistanceFee int64
	DurationFee int64
	StartedAt   int // 0 [0
	EndedAt     int // 7 0)
}
